package com.zw.controller;

import com.alibaba.fastjson2.JSON;
import com.zw.dto.RegisterDto;
import com.zw.utils.Constants;
import com.zw.utils.RSAUtils;
import com.zw.utils.TokenUtils;
import com.zw.vo.LoginBody;
import com.zw.service.SysUserService;
import com.zw.vo.LoginUser;
import com.zw.vo.LoginVO;
import com.zw.vo.ResponseVO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.security.PrivateKey;

@RestController
@Slf4j
@RequestMapping("system")
@Api(value = "系统登录API", tags = "系统登录API")
public class UserLoginController {

    @Autowired
    private SysUserService sysUserService;
    @Value("${dataKey.base64PrivateKey}")
    private String base64PrivateKey;

    // 令牌自定义标识
    @Value("${token.header}")
    private String header;

    // 令牌秘钥
    @Value("${token.secret}")
    private String secret;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 登录用户 redis key
     */
    public static final String LOGIN_TOKEN_KEY = "login_tokens:";

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @ApiOperation("登录")
    @PostMapping("/login")
    public ResponseVO<LoginVO> login(@RequestBody LoginBody loginBody) {
        try {
            // 获取RSA私钥
            PrivateKey privateKey = RSAUtils.getPrivateKey(base64PrivateKey);
            //解密加密密码
            String decryptedData = RSAUtils.decrypt(loginBody.getPassword(), privateKey);
            loginBody.setPassword(decryptedData);
            LoginVO loginVO = sysUserService.login(loginBody.getEmail(), loginBody.getPassword());
            return new ResponseVO(loginVO);
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw new RuntimeException(e.getMessage());
            }
            throw new RuntimeException("用户登录失败，请联系管理员处理！");
        }
    }

    /**
     * 退出登录
     *
     * @param request 登录信息
     * @return 结果
     */
    @ApiOperation("退出登录")
    @PostMapping("/loginOut")
    public ResponseVO<Boolean> login(HttpServletRequest request) {
        Boolean delete = false;
        // 获取请求携带的令牌
        //从前端获取token
        String token = request.getHeader(header);
        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
            token = token.replace(Constants.TOKEN_PREFIX, "");
        }
        if (StringUtils.isNotEmpty(token)) {
            try {
                Claims claims = parseToken(token);
                // 解析对应的权限以及用户信息
                String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
                String userKey = getTokenKey(uuid);
                if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(userKey))) {
                    delete = stringRedisTemplate.delete(userKey);
                }
            } catch (Exception e) {
            }
        }
        return new ResponseVO(delete);
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    private Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }

    private String getTokenKey(String uuid) {
        return LOGIN_TOKEN_KEY + uuid;
    }

}
